package com.dingreading.cloud.soms.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.dto.LoginDataDto;
import com.dingreading.cloud.common.util.*;
import com.dingreading.cloud.common.util.wechat.WxPayBusiness;
import com.dingreading.cloud.soms.dto.MemberChannelDto;
import com.dingreading.cloud.soms.entity.MemberChannel;
import com.dingreading.cloud.soms.entity.Staff;
import com.dingreading.cloud.soms.entity.Stores;
import com.dingreading.cloud.soms.service.MemberChannelService;
import com.dingreading.cloud.soms.service.MembersService;
import com.dingreading.cloud.soms.service.StaffService;
import com.dingreading.cloud.soms.service.StoresService;
import com.dingreading.cloud.soms.util.LoginInfoUtil;
import com.dingreading.cloud.soms.util.redis.RedisService;
import com.mybatisflex.core.paginate.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

@RefreshScope
@RestController
@RequestMapping(value = "/front/memberChannel")
@Api(tags = "门店-会员异业渠道管理")
public class FrontMemberChannelController {

    @Resource
    protected MemberChannelService memberChannelService;
    @Resource
    protected StoresService storesService;
    @Resource
    protected MembersService membersService;
    @Resource
    protected StaffService staffService;
    @Resource
    private RedisService redisService;

    @Value("${mini.store.appId}")
    private String miniAppId;
    @Value("${mini.store.appSecret}")
    private String miniSecret;


    @ApiOperation(value = "分页列表-店长")
    @PostMapping(value = "/pageList", produces = "application/json; charset=UTF-8")
    public R<Object> pageList(
            HttpServletRequest request,
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "联系人姓名/电话/渠道名称/渠道编码") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(value = "启用状态") @RequestParam(value = "enabled", required = false) Integer enabled
    ) {
        R<Object> r = LoginInfoUtil.getLoginDto(request);
        if (R.isError(r)) return r;
        LoginDataDto loginDto = (LoginDataDto) r.getData();

        String queryStoreUid = "";
        String queryStaffUid = "";

        // 获取员工角色
        int role = AccountUtil.isMarketStaff(loginDto.getStoreRoles());
        if (role == 1) {
            queryStoreUid = storeUid;
        } else if (role == 3) {
            // 市场组长
            queryStoreUid = storeUid;
        } else if (role == 4) {
            // 市场人员只能看自己录入的数据，店长和市场组长能看所有数据
            queryStoreUid = storeUid;
            queryStaffUid = staffUid;
        } else {
            return R.fail("员工没有权限");
        }

        Page<MemberChannelDto> pageList = memberChannelService.pageList(pageUtil, corpUid, queryStoreUid, keyword, enabled, queryStaffUid);
        PageBeanDto dto = new PageBeanDto();
        dto.setList(pageList.getRecords());
        dto.setTotal(pageList.getTotalRow());
        return R.ok(dto);
    }


    @ApiOperation(value = "获取信息")
    @PostMapping(value = "/getBean", produces = "application/json; charset=UTF-8")
    public R<Object> getBean(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "uid") @RequestParam(value = "uid") String uid
    ) {
        MemberChannelDto data = memberChannelService.getByStoreUidAndUid(uid);
        return R.ok(data);
    }

    @Transactional(rollbackFor = DescribeException.class)
    @ApiOperation(value = "创建/编辑信息")
    @PostMapping(value = "/newBean", produces = "application/json; charset=UTF-8")
    public R<Object> newBean(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "uid") @RequestParam(value = "uid", required = false) String uid,
            @ApiParam(value = "渠道名称") @RequestParam(value = "name") String name,
            @ApiParam(value = "联系人电话") @RequestParam(value = "fullName", required = false) String fullName,
            @ApiParam(value = "联系人姓名") @RequestParam(value = "mob", required = false) String mob,
            @ApiParam(value = "产品包uid") @RequestParam(value = "productUid", required = false) String productUid,
            @ApiParam(value = "备注") @RequestParam(value = "remark", required = false) String remark,
            @ApiParam(value = "市场人员uid") @RequestParam(value = "refererStaffUid", required = false) String refererStaffUid
    ) {
        R<Object> r = LoginInfoUtil.getLoginDto(request);
        if (R.isError(r)) return r;
        LoginDataDto loginDto = (LoginDataDto) r.getData();

        String source = "";
        // 获取员工角色
        int role = AccountUtil.isMarketStaff(loginDto.getStoreRoles());
        if (role == 1 || role == 2) {
            source = EnumType.Source.STORE.getName();
        } else if (role == 3 || role == 4) {
            // 市场
            source = EnumType.Source.MARKET.getName();
        } else {
            return R.fail("员工没有权限");
        }

        if (StringUtils.isBlank(name))
            return R.fail("请填写正确的渠道名称");

        Stores stores = storesService.getByUid(storeUid);
        if (null == stores) return R.fail("门店获取失败");

        boolean b = memberChannelService.haveName(storeUid, uid, name);
        if (b)
            return R.fail("渠道名称重复了");

        String staffPubPhone = "";
        String staffPriPhone = "";
        String staffNickName = "";
        String staffFullName = "";
        if (StringUtils.isNotBlank(refererStaffUid)) {
            Staff staff = staffService.getByUid(refererStaffUid);
            if (null == staff) return R.fail("市场人员获取失败");

            staffFullName = staff.getFullName();
            if (StringUtils.isBlank(staffFullName))
                return R.fail("请先完善市场人员的全名");
            staffPriPhone = staff.getPriPhone();
//            if (StringUtils.isBlank(staffPriPhone))
//                return R.fail("请先完善市场人员的私人电话");
            staffPubPhone = staff.getPubPhone();
            staffNickName = staff.getNickName();
        }

        MemberChannel data = null;
        if (StringUtils.isBlank(uid)) {
            // 创建
            // 生成渠道标识
            String randomUid = KitUtil.getUuid();
            // 判断uid是否重复
            boolean haveChannelUid = memberChannelService.haveChannelUid(storeUid, randomUid);
            if (haveChannelUid)
                randomUid = KitUtil.getUuid();

            data = new MemberChannel();
            data.setUid(randomUid);
            data.setCorpUid(stores.getCorpUid());
            data.setStoreUid(storeUid);
            data.setStoreName(stores.getStoreName());
            data.setEnabled(1);
            data.setAddStaffUid(staffUid);
            data.setAddStaffName(staffName);
            data.setSource(source);
        } else {
            // 编辑
            data = memberChannelService.getInfo(uid);
            if (null == data)
                return R.fail("渠道获取失败");
            if (data.getSource().equals(EnumType.Source.MARKET.getName())) {
                data.setStoreUid(storeUid);
                data.setStoreName(stores.getStoreName());
            } else if (data.getSource().equals(EnumType.Source.STORE.getName())) {
                if (!storeUid.equals(data.getStoreUid())) {
                    return R.fail("门店录入，不能修改所属门店");
                }
            }
        }
        data.setName(name);
        data.setFullName(fullName);
        data.setMob(mob);
        data.setRefererStaffUid(refererStaffUid);
        data.setRefererStaffName(staffNickName);
        data.setRefererStaffFullName(staffFullName);
        data.setRefererStaffPubPhone(staffPubPhone);
        data.setRefererStaffPriPhone(staffPriPhone);
        data.setProductUid(productUid);
        data.setRemark(remark);
        data.setLastStaffUid(staffUid);
        data.setLastStaffName(staffName);
        memberChannelService.saveOrUpdate(data);

        // 清空缓存
        redisService.setNullLike(RedisParam.STORE_SOURCE_CHANNEL);
        redisService.setNullLike(RedisParam.STORE_CHANNEL);
        return R.ok();
    }


    @ApiOperation(value = "删除信息")
    @PostMapping(value = "/dropBean", produces = "application/json; charset=UTF-8")
    public R<Object> dropBean(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "uid") @RequestParam(value = "uid") String uid
    ) {
        R<Object> r = LoginInfoUtil.getLoginDto(request);
        if (R.isError(r)) return r;
        LoginDataDto loginDto = (LoginDataDto) r.getData();

        // 获取员工角色
        int role = AccountUtil.isMarketStaff(loginDto.getStoreRoles());

        MemberChannel data = memberChannelService.getInfo(uid);
        if (null == data) return R.fail("渠道获取失败");

        String source = data.getSource();

        if (source.equals(EnumType.Source.STORE.getName()) && (role == 3 || role == 4)) {
            // 判断信息来源是不是门店录入
            return R.fail("门店录入，不能操作");
        }

        // 删除前先判断会员使用
        boolean b = membersService.haveChannelUid(storeUid, uid);
        if (b) return R.fail("会员已使用，不能操作");

        int i = memberChannelService.dropBean(storeUid, uid);
        if (i <= 0) return R.fail("删除失败");

        // 清空缓存
        redisService.setNullLike(RedisParam.STORE_SOURCE_CHANNEL);
        redisService.setNullLike(RedisParam.STORE_CHANNEL);
        return R.ok();
    }


    @ApiOperation(value = "更新启用状态")
    @PostMapping(value = "/updateEnabled", produces = "application/json; charset=UTF-8")
    public R<Object> updateEnabled(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "uid") @RequestParam(value = "uid") String uid,
            @ApiParam(value = "是否禁用 1.启用 0.禁用") @RequestParam(value = "enabled") Integer enabled
    ) {
        boolean l = memberChannelService.updateEnabled(storeUid, uid, enabled, staffUid, staffName);
        if (!l) return R.fail("更新服务状态失败");

        // 清空缓存
        redisService.setNullLike(RedisParam.STORE_SOURCE_CHANNEL);
        redisService.setNullLike(RedisParam.STORE_CHANNEL);
        return R.ok();
    }


    @ApiOperation(value = "获取可用的异业渠道")
    @PostMapping(value = "/getList", produces = "application/json; charset=UTF-8")
    public R<Object> getList(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName
    ) {
        String redisKey = RedisParam.STORE_CHANNEL + storeUid;
        String json = (String) redisService.get(redisKey);

        List<MemberChannelDto> list = null;
        if (StringUtils.isNotBlank(json)) {
            list = JSONArray.parseArray(json, MemberChannelDto.class);
        } else {
            list = memberChannelService.listByEnabled(storeUid);

            // 缓存2小时
            json = JSONArray.toJSONString(list);
            redisService.set(redisKey, json, 7200);
        }
        return R.ok(list);
    }


    @ApiOperation(value = "获取客户来源和异业渠道")
    @PostMapping(value = "/getSourceAndChannels", produces = "application/json; charset=UTF-8")
    public R<Object> getSourceAndChannels(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName
    ) {
        String redisKey = RedisParam.STORE_SOURCE_CHANNEL + storeUid;
        String json = (String) redisService.get(redisKey);

        JSONArray array = null;
        if (StringUtils.isNotBlank(json)) {
            array = JSONArray.parseArray(json);
        } else {
            List<MemberChannelDto> list = memberChannelService.listByEnabled(storeUid);

            array = new JSONArray();
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("name", "地推");
            jsonObject1.put("uid", "DT");
            array.add(jsonObject1);
            JSONObject jsonObject2 = new JSONObject();
            jsonObject2.put("name", "异业");
            jsonObject2.put("uid", "YY");
            jsonObject2.put("channels", list);
            array.add(jsonObject2);
            JSONObject jsonObject3 = new JSONObject();
            jsonObject3.put("name", "转介绍");
            jsonObject3.put("uid", "ZJ");
            array.add(jsonObject3);
            JSONObject jsonObject4 = new JSONObject();
            jsonObject4.put("name", "自然到访");
            jsonObject4.put("uid", "ZR");
            array.add(jsonObject4);
            JSONObject jsonObject5 = new JSONObject();
            jsonObject5.put("name", "其他");
            jsonObject5.put("uid", "QT");
            array.add(jsonObject5);

            // 缓存2小时
            json = array.toJSONString();
            redisService.set(redisKey, json, 7200);
        }

        return R.ok(array);
    }


    @ApiOperation(value = "获取录入会员的小程序码图片")
    @PostMapping(value = "/getMiniCode", produces = "application/json; charset=UTF-8")
    public R<Object> getMiniCode(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "渠道uid") @RequestParam(value = "uid") String uid
    ) throws Exception {
        Stores stores = storesService.getByUid(storeUid);
        if (null == stores)
            return R.fail("门店获取失败");

        MemberChannel channel = memberChannelService.getInfo(uid);
        if (null == channel) return R.fail("渠道获取失败");
        if (StringUtils.isNotBlank(channel.getMiniUrl()))
            return R.fail("已有小程序码");

        // 生产小程序标识
        String scene = uid;
        // 小程序路径
        String path = "pages/index/index";

        // 获取小程序accessToken
        String redisKey = RedisParam.WEIXIN_ACCESS_TOKEN + miniAppId;
        String accessToken = (String) redisService.get(redisKey);
        if (StringUtils.isBlank(accessToken)) {
            accessToken = WxPayBusiness.Init().getAccessToken(miniAppId, miniSecret);
            if (StringUtils.isBlank(accessToken))
                return R.fail("微信小程序access_token获取失败");
            redisService.set(redisKey, accessToken, 7200);
        }
        // 生成小程序码
        JSONObject jsonObject = WxMiniUtil.Init().getCodeUnLimit(accessToken, path, scene, 280);
        if (null == jsonObject)
            return R.fail("小程序码获取失败");
        Integer status = jsonObject.getInteger("status");

        if (status.equals(0)) {
            byte[] bytes = jsonObject.getBytes("data");
            // 图片下载到本地
            String imgUrl = WxMiniUtil.Init().buff2Image(bytes);

            // 更新渠道小程序码的图片地址
            if (StringUtils.isNotBlank(imgUrl))
                memberChannelService.updateMiniUrl(storeUid, uid, imgUrl, staffUid, staffName);
            return R.ok(imgUrl);
        } else {
            String data = jsonObject.getString("data");
            JSONObject jsonObj = JSONObject.parseObject(data);
            Integer errcode = jsonObj.getInteger("errcode");
            String errmsg = jsonObj.getString("errmsg");
            return R.fail("小程序码获取失败" + errcode + "," + errmsg);
        }
    }

}
